package com.exam.scjp5.objectives.section_4;

public class ExampleSynchronizedTest2
{

    /**
     * @param args
     */
    public static void main(String[] args)
    {
        Something s1 = new Something();
        Something s2 = new Something();

        SharedJob sj1 = new SharedJob(s1);
        SharedJob sj2 = new SharedJob(s2);

        Thread t1 = new Thread(sj1, "Thread-1 Group A ");
        Thread t2 = new Thread(sj1, "Thread-2 Group A ");
        Thread t3 = new Thread(sj2, "Thread-1 Group B");
        Thread t4 = new Thread(sj2, "Thread-2 Group B");

        t1.start();
        t2.start();
        t3.start();
        t4.start();

        synchronized (Something.class)
        {
            for (int i = 0; i < 5; i++)
            {
                System.out.println("Wait me : " + i);
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

        try
        {
            t1.join();
            t2.join();
            t3.join();
            t4.join();

            System.out.println("Final value in s1 : " + s1.getValue());
            System.out.println("Final value in s2 : " + s2.getValue());
        }
        catch (InterruptedException e)
        {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

}

class Something
{
    private int sharedInt = 0;

    public void increment()
    {
        sharedInt++;
    }

    public int getValue()
    {
        return sharedInt;
    }
}

class SharedJob implements Runnable
{
    Something so = null;

    public SharedJob(Something o)
    {
        this.so = o;
    }

    public void run()
    {

        // Remove the following comment and see the thread executions.
        //synchronized(Something.class)
        //synchronized (this.so)
        {
            for (int i = 0; i < 10; i++)
            {
                this.so.increment();
                System.out.println(i + " -> " + Thread.currentThread().getName() + " : " + this.so.getValue());
                try
                {
                    Thread.sleep(1000);
                }
                catch (InterruptedException e)
                {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}